package com.wzx.server.core;

import com.wzx.api.MsgPack;
import com.wzx.api.RpcRequest;
import com.wzx.api.RpcService;
import com.wzx.api.Utils;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Map;

@Component
@ChannelHandler.Sharable
public class RpcServerHandler extends SimpleChannelInboundHandler<String> implements ApplicationContextAware {

    static Map<String, Object> cacheRpcServiceBeanMap;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);

        System.out.println("服务端：收到连接了");
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        NioSocketChannel channel = (NioSocketChannel)ctx.channel();


        System.out.println(channel.localAddress().getPort() + "服务端：收到消息了");
        RpcRequest rpcRequest = Utils.objectMapper.readValue(msg, RpcRequest.class);
        Object o = cacheRpcServiceBeanMap.get(rpcRequest.getServiceName());
        Method declaredMethod = o.getClass().getDeclaredMethod(rpcRequest.getMethodName(), rpcRequest.getParamTypes());
        Object invoke = declaredMethod.invoke(o, rpcRequest.getArgs());

        MsgPack msgPack = new MsgPack();
        msgPack.setMsg("当前数据由：" + channel.localAddress() + " 提供服务。");
        msgPack.setData(invoke);
        ctx.writeAndFlush(Utils.objectMapper.writeValueAsString(msgPack));
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        cacheRpcServiceBeanMap = applicationContext.getBeansWithAnnotation(RpcService.class);
    }
}
